package org.c797797ty.railway.service;

import org.c797797ty.railway.manager.UserSessionManager;
import org.c797797ty.railway.model.User;
import org.c797797ty.railway.util.ConcurrentDBUtil;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author C797797ty
 * @data 2025/11/4 14:35
 */

/**
 * 高并发票务服务 - 支持多用户同时购票
 */
public class ConcurrentTicketService {
    private static final ReentrantLock ticketLock = new ReentrantLock();

    // 显示车票
    public static void displayTickets() {
        try {
            ConcurrentDBUtil.executeQuery(rs -> {
                System.out.println("\n===== 所有车票信息 =====");
                String currentRoute = "";
                boolean hasTickets = false;
                while (rs.next()) {
                    hasTickets = true;
                    String route = rs.getString("departure") + "→" + rs.getString("destination");
                    if (!route.equals(currentRoute)) {
                        System.out.println("\n=== " + route + " ===");
                        currentRoute = route;
                    }
                    System.out.printf("[%s] %s | %s | %s | ¥%.2f | %s | 余票: %d\n",
                            rs.getString("ticket_id"),
                            rs.getString("time"),
                            rs.getString("time_slot"),
                            rs.getString("departure"),
                            rs.getDouble("price"),
                            rs.getString("seat_class"),
                            rs.getInt("available_seats"));
                }

                if (!hasTickets) {
                    System.out.println("暂无车票信息");
                }
                return null;
            }, "SELECT * FROM tickets");
        } catch (SQLException e) {
            System.err.println("查询失败: " + e.getMessage());
        }
    }

    // 订票逻辑（使用锁防止超卖）
    public static void bookTicket(String token) {
        User user = UserSessionManager.getSession(token);
        if (user == null) {
            System.out.println("用户未登录或会话过期");
            return;
        }

        Scanner scanner = new Scanner(System.in);
        System.out.print("出发地: ");
        String departure = scanner.nextLine();
        System.out.print("目的地: ");
        String destination = scanner.nextLine();

        // 显示可用车次
        System.out.println("\n===== 可用车次 =====");
        try {
            Boolean hasTickets = ConcurrentDBUtil.executeQuery(rs -> {
                boolean found = false;
                while (rs.next()) {
                    found = true;
                    System.out.printf("[%s] %s → %s | %s | %s | %s | ¥%.2f | 余票: %d\n",
                            rs.getString("ticket_id"),
                            rs.getString("departure"),
                            rs.getString("destination"),
                            rs.getString("time"),
                            rs.getString("time_slot"),
                            rs.getString("seat_class"),
                            rs.getDouble("price"),
                            rs.getInt("available_seats"));
                }

                if (!found) {
                    System.out.println("暂无可用车次");
                }
                return found;
            }, "SELECT * FROM tickets WHERE departure = ? AND destination = ?", departure, destination);

            if (hasTickets == null || !hasTickets) {
                return;
            }
        } catch (SQLException e) {
            System.err.println("查询失败: " + e.getMessage());
            return;
        }

        // 选择车次和座位
        System.out.print("\n请输入要预订的车次ID: ");
        String ticketId = scanner.nextLine();
        System.out.print("请选择座位等级 (A/B/C/D/E/F): ");
        String selectedClass = scanner.nextLine().toUpperCase();

        ticketLock.lock();
        try {
            ConcurrentDBUtil.executeInTransaction(conn -> {
                // 验证车次和座位
                try (PreparedStatement stmt = conn.prepareStatement(
                        "SELECT * FROM tickets WHERE ticket_id = ? AND seat_class = ? FOR UPDATE")) {
                    stmt.setString(1, ticketId);
                    stmt.setString(2, selectedClass);

                    try (ResultSet rs = stmt.executeQuery()) {
                        if (!rs.next()) {
                            System.out.println("无效的车次或座位等级");
                            return;
                        }

                        int availableSeats = rs.getInt("available_seats");
                        if (availableSeats <= 0) {
                            System.out.println("该座位等级余票不足");
                            return;
                        }

                        // 更新余票
                        try (PreparedStatement updateStmt = conn.prepareStatement(
                                "UPDATE tickets SET available_seats = ? WHERE ticket_id = ?")) {
                            updateStmt.setInt(1, availableSeats - 1);
                            updateStmt.setString(2, ticketId);
                            updateStmt.executeUpdate();
                        }

                        // 添加订单
                        try (PreparedStatement orderStmt = conn.prepareStatement(
                                "INSERT INTO user_tickets (user_id, ticket_id, seat_class) VALUES (?, ?, ?)")) {
                            orderStmt.setInt(1, user.getId());
                            orderStmt.setString(2, ticketId);
                            orderStmt.setString(3, selectedClass);
                            orderStmt.executeUpdate();
                        }

                        // 发送系统消息
                        sendSystemMessage(user, ticketId, selectedClass, rs);
                    }
                }
                System.out.println("订票成功！");
            });

        } catch (SQLException e) {
            System.err.println("订票失败: " + e.getMessage());
        } finally {
            ticketLock.unlock();
        }
    }


    // 发送系统消息
    private static void sendSystemMessage(User user, String ticketId, String seatClass, ResultSet rs) throws SQLException {
        try {
            String message = "【系统消息】 您已购买高铁票 ：" +
                    rs.getString("departure") + " 到 " +
                    rs.getString("destination") + " " +
                    rs.getString("time") + " " +
                    seatClass;

            ConcurrentDBUtil.executeInTransaction(conn -> {
                try (PreparedStatement stmt = conn.prepareStatement(
                        "INSERT INTO system_messages (user_id, message_content) VALUES (?, ?)")) {
                    stmt.setInt(1, user.getId());
                    stmt.setString(2, message);
                    stmt.executeUpdate();
                }
            });
        } catch (SQLException e) {
            System.err.println("发送消息失败: " + e.getMessage());
        }
    }


    // 为他人订票逻辑
    public static void bookTicketForOther(String token) {
        User currentUser = UserSessionManager.getSession(token);
        if (currentUser == null) {
            System.out.println("用户未登录或会话过期");
            return;
        }

        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入要为谁订票的用户名: ");
        String targetUsername = scanner.nextLine();

        // 查询目标用户
        User targetUser = null;
        try {
            targetUser = ConcurrentDBUtil.executeQuery(rs -> {
                if (rs.next()) {
                    return new User(rs.getInt("id"), rs.getString("username"), rs.getString("password"));
                }
                return null;
            }, "SELECT * FROM users WHERE username = ?", targetUsername);
        } catch (SQLException e) {
            System.err.println("查询用户失败: " + e.getMessage());
            return;
        }

        if (targetUser == null) {
            System.out.println("目标用户不存在");
            return;
        }

        System.out.print("出发地: ");
        String departure = scanner.nextLine();
        System.out.print("目的地: ");
        String destination = scanner.nextLine();

        // 显示可用车次
        System.out.println("\n===== 可用车次 =====");
        try {
            Boolean hasTickets = ConcurrentDBUtil.executeQuery(rs -> {
                boolean found = false;
                while (rs.next()) {
                    found = true;
                    System.out.printf("[%s] %s → %s | %s | %s | %s | ¥%.2f | 余票: %d\n",
                            rs.getString("ticket_id"),
                            rs.getString("departure"),
                            rs.getString("destination"),
                            rs.getString("time"),
                            rs.getString("time_slot"),
                            rs.getString("seat_class"),
                            rs.getDouble("price"),
                            rs.getInt("available_seats"));
                }

                if (!found) {
                    System.out.println("暂无可用车次");
                }
                return found;
            }, "SELECT * FROM tickets WHERE departure = ? AND destination = ?", departure, destination);

            if (hasTickets == null || !hasTickets) {
                return;
            }
        } catch (SQLException e) {
            System.err.println("查询失败: " + e.getMessage());
            return;
        }

        // 选择车次和座位
        System.out.print("\n请输入要预订的车次ID: ");
        String ticketId = scanner.nextLine();
        System.out.print("请选择座位等级 (A/B/C/D/E/F): ");
        String selectedClass = scanner.nextLine().toUpperCase();

        ticketLock.lock();
        try {
            User finalTargetUser = targetUser;
            ConcurrentDBUtil.executeInTransaction(conn -> {
                // 验证车次和座位
                try (PreparedStatement stmt = conn.prepareStatement(
                        "SELECT * FROM tickets WHERE ticket_id = ? AND seat_class = ? FOR UPDATE")) {
                    stmt.setString(1, ticketId);
                    stmt.setString(2, selectedClass);

                    try (ResultSet rs = stmt.executeQuery()) {
                        if (!rs.next()) {
                            System.out.println("无效的车次或座位等级");
                            return;
                        }

                        int availableSeats = rs.getInt("available_seats");
                        if (availableSeats <= 0) {
                            System.out.println("该座位等级余票不足");
                            return;
                        }

                        // 更新余票
                        try (PreparedStatement updateStmt = conn.prepareStatement(
                                "UPDATE tickets SET available_seats = ? WHERE ticket_id = ?")) {
                            updateStmt.setInt(1, availableSeats - 1);
                            updateStmt.setString(2, ticketId);
                            updateStmt.executeUpdate();
                        }

                        // 添加订单
                        try (PreparedStatement orderStmt = conn.prepareStatement(
                                "INSERT INTO user_tickets (user_id, ticket_id, seat_class) VALUES (?, ?, ?)")) {
                            orderStmt.setInt(1, finalTargetUser.getId());
                            orderStmt.setString(2, ticketId);
                            orderStmt.setString(3, selectedClass);
                            orderStmt.executeUpdate();
                        }

                        // 发送系统消息给目标用户
                        sendSystemMessage(finalTargetUser, ticketId, selectedClass, rs);
                    }
                }
                System.out.println("为 " + targetUsername + " 订票成功！");
            });

        } catch (SQLException e) {
            System.err.println("订票失败: " + e.getMessage());
        } finally {
            ticketLock.unlock();
        }
    }
}